package face.pay.api.payter.channel.paytype.wechat;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.face.pay.WxApiConfig;
import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import face.pay.api.payter.channel.paytype.AbstractPayType;
import face.pay.api.payter.channel.paytype.wechat.api.ApiWxPayQuery;
import face.pay.api.wechat.param.PayParam;
import face.pay.constant.OrderStatus;
import face.pay.constant.OrderType;
import face.pay.constant.PayType;
import face.pay.entity.EnterpriseInfo;
import face.pay.entity.OemInfo;
import face.pay.entity.OrderInfo;
import face.pay.entity.StoreInfo;
import face.pay.util.IpUtils;
import face.pay.util.ResultMessage;
import face.pay.util.bean.JavaBeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信扫码核销优惠券
 */
@Component
@Slf4j
public class WXQrSharingPay extends AbstractPayType {

    private static final String domain = "api.mch.weixin.qq.com";

    private static final  String urlSuffix = "/pay/micropay";

    @Autowired
    ApiWxPayQuery apiPayQuery;


    @Override
    public ResultMessage pay(JSONObject json) {

        try {

            log.info("扫码支付优惠券订单:" + json.toJSONString());

            PayParam payParam = json.toJavaObject(PayParam.class);

            Integer terminalId = json.getInteger("terminalId");

            Long total_fee = payParam.getTotal_fee()==null?new Long(0):payParam.getTotal_fee();

            Long actFee = payParam.getAct_fee()==null?new Long(0):payParam.getAct_fee();

            String authCode = payParam.getAuth_code();

            String out_trade_no = payParam.getOut_trade_no();
            String channelCode = json.getString("channelCode");

            Long cardDetailId =  payParam.getCardDetailId();

            Long orderId = Long.valueOf(out_trade_no);
            log.info("查找订单: orderId" + orderId);

            OrderInfo orderInfo = this.orderInfoDao.getById(orderId);

            if (orderInfo != null) {

                log.info("订单信息: " + orderInfo.toString());

                if (!new Integer(0).equals(orderInfo.getStatus())) {
                    log.info("订单已经被处理，重新发起支付请求 ");
                    return ResultMessage.createFail("订单已经被处理，重新发起支付请求");
                }
                String safe = this.payCardSafe(orderInfo,cardDetailId, terminalId, total_fee,actFee);
                if (StringUtils.isNotBlank(safe)) {
                    log.info("交易信息不正确，中断支付");
                    return ResultMessage.createFail(safe);
                }else {

                    Integer oemId = orderInfo.getOemId();

                    Integer storeId = orderInfo.getStoreId();

                    OemInfo oemInfo = this.oemInfoDao.getOemInfoById(oemId);

                    WxApiConfig wxApiConfig =  this.iWxPayConfigServer.getConfig(oemId);

                    if(wxApiConfig.validate()){

                        WXPayRequest wxPayRequest = new WXPayRequest(wxApiConfig);

                        String type = oemInfo.getType();

                        StoreInfo storeInfo = this.storeInfoDao.getById(storeId);

                        EnterpriseInfo enterpriseInfo = this.enterpriseInfoDao.getById(storeInfo.getEnterpriseId());

                        String appId = wxApiConfig.getAppID();
                        String apiKey = wxApiConfig.getKey();
                        String mchId = wxApiConfig.getMchID();

                        String subMchId = enterpriseInfo.getWxSubMchId();

                        if (StringUtils.isBlank(subMchId)) {
                            log.info("商家商户号错误");
                            return ResultMessage.createFail("商家商户号错误");
                        }

                        payParam.setAppid(appId);
                        payParam.setMch_id(mchId);
                        payParam.setSub_mch_id(subMchId);

                        String body = storeInfo.getName() + "-线下支付";
                        String ip = IpUtils.getIpAddress();

                        if(cardDetailId!=null && cardDetailId>0){
                            payParam.setTotal_fee(actFee);
                        }

                        payParam.setSpbill_create_ip(ip);
                        payParam.setBody(body);

                        String nonce_str = WXPayUtil.generateNonceStr();

                        payParam.setNonce_str(nonce_str);

                        Map<String, String> map = JavaBeanUtils.toMap(payParam);
                        map.put("auth_code", payParam.getAuth_code());

                        if(cardDetailId!=null && cardDetailId>0){
                           map.put("profit_sharing","Y");
                           orderInfo.setCardDetailId(cardDetailId);
                        }


                        String xml = WXPayUtil.generateSignedXml(map, apiKey);
                        log.info("扫码支付>>>>>推送到微信服务器消息xml" + xml);


                        String result = wxPayRequest.requestOnce(domain, urlSuffix, xml, false);
                        log.info("扫码支付<<<<<<返回结果 " + result);
                        Map<String, String> resultMap = WXPayUtil.xmlToMap(result);

                        String messege = "正在支付";

                        orderInfo.setPayType(PayType.SQR);
                        orderInfo.setChannelCode(channelCode);
                        orderInfo.setType(OrderType.WECHAT);
                        orderInfo.setStatus(0);
                        orderInfo.setSharing(0);
                        orderInfo.setScene(0);
                        orderInfo.setServiceFee(new Long(0));
                        orderInfo.setActFee(actFee);
                        orderInfo.setActInnerFee(actFee);
                        orderInfo.setProfitSign(0);
                        String err_code = resultMap.get("err_code");

                        if (!WXPayUtil.isSuccess(resultMap)  && !OrderStatus.USERPAYING.equalsIgnoreCase(err_code)){
                            messege  = resultMap.get("err_code_des");
                            log.info("调用接口失败");
                            this.orderInfoDao.updatePayInfo(orderInfo);
                            return ResultMessage.createFail(messege);

                        }else {

                            /**
                             * 订单推送成功
                             */
                            String trade_no = resultMap.get("transaction_id");

                            String openid=resultMap.get("openid");

                            orderInfo.setTradeNo(trade_no);
                            orderInfo.setPayUserSign(openid);
                            //存入authCode
                            orderInfo.setPayCode(authCode);

                            this.orderInfoDao.updatePayInfo(orderInfo);

                            /**
                             * 异步去微信查询支付状态
                             */
                            apiPayQuery.orderStatusCheck(orderId,subMchId,wxApiConfig,oemInfo);
                            Map<String,String> dataMap =  new HashMap<>();

                            dataMap.put("return_code","SUCCESS");
                            dataMap.put("result_code","SUCCESS");
                            dataMap.put("type",OrderType.WECHAT);
                            dataMap.put("payType",PayType.SQR);
                            dataMap.put("out_trade_no",out_trade_no);
                            dataMap.put("act_fee", String.valueOf(actFee));
                            dataMap.put("total_fee", String.valueOf(total_fee));

                            ResultMessage resultMessage = ResultMessage.createSuccess(messege,dataMap);

                            log.info("扫码支付订单推送成功>>>>>>>:返回设备请求");
                            log.info(JSON.toJSONString(resultMessage));
                            return resultMessage;
                        }

                    }else {
                        log.info("配置错误");
                        return ResultMessage.createFail("配置错误");
                    }

                }

            } else {
                return ResultMessage.createFail("订单不存在或订单已失效");
            }

        } catch (Exception e) {
            log.error("扫码支付异常", e);
        }

        return ResultMessage.createFail("支付失败");

    }
}
